#include "header/pyramid_mosaic.h"


NodePtr createMosaic(int index){

	// User definable constants

	float padding = 1;
	int boxsize = 4;


	Int32 ImageWidth, ImageHeight;

	
	
	/*  http://opensg.vrsource.org/trac/wiki/Tutorial/OpenSG1/Traversal#Tutorial-GraphTraversal
	 // define the Graph Op Sequence here
	 GraphOpSeq *graphOperator = new GraphOpSeq;
	    
	 //first we verify the geometry
	 graphOperator->addGraphOp(new VerifyGeoGraphOp);
	 //merge geometry and transformations
	 //graphOperator->addGraphOp(new MergeGraphOp);
	 //merge identical field containers
	 graphOperator->addGraphOp(new SharePtrGraphOp);
	 //verify again
	 graphOperator->addGraphOp(new VerifyGeoGraphOp);
	*/
	    
	
	NodePtr mosaicNode=Node::create();
	
	beginEditCP(mosaicNode);
		mosaicNode->setCore(Group::create());
	endEditCP(mosaicNode);

	ImagePtr mosaicSource = Image::create();

	switch (index){
	case 1:
	mosaicSource->read("materials/mosaic_1.jpg");
	break;
	case 2:
	mosaicSource->read("materials/mosaic_2.jpg");
	break;
	case 3:
	mosaicSource->read("materials/mosaic_3.jpg");
	break;
	case 4:
	mosaicSource->read("materials/mosaic_4.jpg");
	break;
	}


	ImageWidth=mosaicSource->getWidth();
	ImageHeight=mosaicSource->getHeight();
	
	UInt8 *p = mosaicSource->getData();

#ifdef DEBUG
cout << "DEBUG: Image size of mosaic is: " << ImageWidth << " " << ImageHeight << endl;
cout << "DEBUG: Image BPP: " << mosaicSource->getBpp() << endl;
#endif

	// Read Colors from file

int i=0;
int x=0;
int y=0;

float red[800][800];
float green[800][800];
float blue[800][800];

for (i=0;i<ImageWidth*ImageHeight;i++,x++){

		if (x>=ImageWidth){
			x=0;
			y+=1;
		}

		float redtemp=*p;
		float greentemp=*(p+1);
		float bluetemp=*(p+2);

		redtemp=redtemp/255;
		greentemp=greentemp/255;
		bluetemp=bluetemp/255;

		red[x][y]   = redtemp;
		green[x][y] = greentemp;
		blue[x][y]  = bluetemp;


#ifdef DEBUG
cout << "DEBUG: RGB value of this pixel (" << x << "|" << y << "):" << redtemp << " " << greentemp << " " << bluetemp <<endl;
#endif
		p+=3;
}


	// test (erstellen neuer objekte vermeiden)
	//SimpleMaterialPtr newMosaicPieceMat = SimpleMaterial::create();
	GeometryPtr newMosaicPieceGeo; //= GeometryPtr::dcast(newMosaicPiece->getCore());
	
	//graphOperator->run(mosaicNode);

	Matrix m;

	int px=0;
	int py=0;

	for (int y=0;y<ImageHeight;y+=15,py++){


#ifdef DEBUG
cout << "DEBUG: y=" << y << endl;
#endif


		for (int x=0;x<ImageWidth;x+=15,px++){


#ifdef DEBUG
cout << "DEBUG: x=" << x << endl;
#endif


		NodePtr newMosaicPiece=makeBox(boxsize,boxsize,boxsize,1,1,1);
		//NodePtr newMosaicPiece=makePlane(boxsize,boxsize,1,1);

		TransformPtr tnewMosaicPiece = Transform::create();
		beginEditCP(tnewMosaicPiece, Transform::MatrixFieldMask);
			m.setIdentity();
			m.setTranslate(0.0,py*(boxsize+padding),px*(boxsize+padding));
			tnewMosaicPiece->setMatrix(m);
		endEditCP(tnewMosaicPiece, Transform::MatrixFieldMask);

		NodePtr newMosaicPiece_Transformation = Node::create();

		beginEditCP(newMosaicPiece_Transformation);
			newMosaicPiece_Transformation->setCore(tnewMosaicPiece);
			newMosaicPiece_Transformation->addChild(newMosaicPiece);
		endEditCP(newMosaicPiece_Transformation);

		SimpleMaterialPtr newMosaicPieceMat = SimpleMaterial::create();
		beginEditCP(newMosaicPieceMat); 
			newMosaicPieceMat->setAmbient(Color3f(red[x][y], green[x][y], blue[x][y]));    
			newMosaicPieceMat->setDiffuse(Color3f(red[x][y], green[x][y], blue[x][y]));
		endEditCP(newMosaicPieceMat);

		//GeometryPtr newMosaicPieceGeo = GeometryPtr::dcast(newMosaicPiece->getCore());
		newMosaicPieceGeo = GeometryPtr::dcast(newMosaicPiece->getCore());
		beginEditCP(newMosaicPieceGeo);
			newMosaicPieceGeo->setMaterial(newMosaicPieceMat);
		endEditCP(newMosaicPieceGeo);

		beginEditCP(mosaicNode);
			mosaicNode->addChild(newMosaicPiece_Transformation);
		endEditCP(mosaicNode);
		}
	px=0;
	}
	
	return mosaicNode;
}

